package com.wu.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;

import com.wu.client.constant.ResTypeEnum;
import com.wu.client.dao.redis.Likes;
import com.wu.client.service.MainCommentsService;
import com.wu.client.service.UserLikesService;
import com.wu.client.utils.DateUtil;
import com.wu.client.utils.PageRespUtil;
import com.wu.client.vo.req.comment.MainCommentReq;
import com.wu.client.vo.res.PageResp;
import com.wu.client.vo.res.comment.MainCommentAddResp;
import com.wu.client.vo.res.comment.MainCommentResp;
import com.wu.mongo.MainComment;
import com.wu.mongo.ReplyComment;
import com.wu.mysql.entiy.UserDO;
import com.wu.mysql.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class MainCommentsServiceImpl implements MainCommentsService {
    private final MongoTemplate mongoTemplate;
    private final UserMapper userMapper;
    private final UserLikesService userLikesService;
    @Override
    public PageResp<MainCommentResp> getMainCommentsInPage(String contentId, String contentType, Long userId, Integer page, Integer limit) {
        Integer type = ResTypeEnum.getCodeByType(contentType);

        // 1. 设置分页请求
        Pageable pageable = PageRequest.of(page-1, limit, Sort.by(Sort.Order.asc("createdAt")));  // 按照 createdAt 降序排序

        // 2. 创建 Query 对象
        Query query = new Query();
        query.addCriteria(Criteria.where("contentType").is(type)
                .and("contentId").is(contentId));
        query.with(pageable); // 设置分页和排序

        // 3. 执行查询
        long totalCount = mongoTemplate.count(query, MainComment.class); // 查询总记录数
        List<MainComment> results = mongoTemplate.find(query, MainComment.class);  // 查询结果

        if (CollectionUtil.isNotEmpty(results)) {
            // 提取用户ID和评论ID列表
            List<Long> userIds = results.stream().map(MainComment::getUseId).distinct().collect(Collectors.toList());
            List<ObjectId> resIds = results.stream().map(MainComment::getId).collect(Collectors.toList());

            // 查询用户点赞信息
            Map<ObjectId, Likes> ifLike = userLikesService.checkUserIfLike(ResTypeEnum.COMMENT, userId, resIds);

            // 查询用户资料
            List<UserDO> userProfileDOS = userMapper.selectBatchIds(userIds);
            Map<Long, UserDO> userMap = userProfileDOS.stream().collect(Collectors.toMap(UserDO::getId, userDO -> userDO));

            // 一次性查询所有评论的回复数量
            Map<ObjectId, Long> replyCountMap = getReplyCountForComments(resIds);

            // 转换评论数据
            List<MainCommentResp> mainCommentRespList = results.stream().map(comment -> {
                MainCommentResp resp = BeanUtil.copyProperties(comment, MainCommentResp.class);
                resp.setCreatedAt(DateUtil.format(comment.getCreatedAt()));
                UserDO userDO = userMap.get(comment.getUseId());
                if (ObjectUtil.isNotNull(userDO)) {
                    resp.setUsername(userDO.getUsername());
                    resp.setAvatar(userDO.getAvatar());
                    resp.setUserId(userDO.getId());
                }
                // 获取评论的点赞信息
                Likes likes = ifLike.get(comment.getId());
                if (ObjectUtil.isNotNull(likes)) {
                    resp.setLikeCount(likes.getCount());
                    resp.setIsLiked(likes.getIsLiked());
                }
                // 获取评论的回复数量
                resp.setReplyCount(replyCountMap.getOrDefault(comment.getId(), 0L));
                return resp;
            }).collect(Collectors.toList());
            mainCommentRespList.get(0).setIsTop(true);
            return PageRespUtil.buildPageResp(page, limit, totalCount, mainCommentRespList);
        }
        return new PageResp<>();
    }

    @Override
    public MainCommentAddResp addComment(MainCommentReq mainCommentReq) {
        Date now = new Date();
        Integer type = ResTypeEnum.getCodeByType(mainCommentReq.getContentType());
        MainComment mainComment = new MainComment();
        mainComment.setContentId(mainCommentReq.getContentId());
        mainComment.setContentType(type);
        mainComment.setContent(mainCommentReq.getContent());
        mainComment.setUseId(mainCommentReq.getUserId());
        mainComment.setCreatedAt(now);
        mongoTemplate.save(mainComment);
        MainCommentAddResp mainCommentAddResp = BeanUtil.copyProperties(mainComment, MainCommentAddResp.class,"createdAt");
        mainCommentAddResp.setCreatedAt(DateUtil.format(mainComment.getCreatedAt()));
        return mainCommentAddResp;
    }

    @Override
    public void deleteMainComment(String mainCommentId) {
        mongoTemplate.remove(new Query(Criteria.where("id").is(new ObjectId(mainCommentId))), MainComment.class);
        mongoTemplate.remove(new Query(Criteria.where("parentId").is(new ObjectId(mainCommentId))), ReplyComment.class);
    }

    private Map<ObjectId, Long> getReplyCountForComments(List<ObjectId> commentIds) {
        Query replyQuery = new Query(Criteria.where("parentId").in(commentIds));
        List<ReplyComment> replies = mongoTemplate.find(replyQuery, ReplyComment.class);
        // 统计每个评论的回复数量
        return replies.stream()
                .collect(Collectors.groupingBy(ReplyComment::getParentId, Collectors.counting()));
    }

}
